﻿using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Windows;
using System.Xml;
using System.Xml.Serialization;
using ExchangeExample.WP7.Models;
using VB;

namespace ExchangeExample.WP7.ViewModels
{
    public class MainViewModel : INotifyPropertyChanged
    {
        private RatesList _RatesList;
        private ObservableCollection<Rate> _Rates;
        public ObservableCollection<Rate> Rates
        {
            get
            {
                return _Rates;
            }
            private set
            {
                _Rates = value;
                NotifyPropertyChanged("Rates");
            }
        }

        public DateTime LastUpdate
        {
            get
            {
                return (DateTime)Common.Constants.settings["LastUpdateDate"];
            }
            private set
            {
                Common.Constants.settings["LastUpdateDate"] = value;
                Common.Constants.settings.Save();
                NotifyPropertyChanged("LastUpdate");
            }
        }

        public bool IsDataLoaded { get; private set; }

        private bool _IsProgressVisible;
        public bool IsProgressVisible
        {
            get
            {
                return _IsProgressVisible;
            }
            private set
            {
                _IsProgressVisible = value;
                NotifyPropertyChanged("IsProgressVisible");
            }
        }

        public MainViewModel()
        {
            Rates = new ObservableCollection<Rate>();
        }

        #region Load Data

        public void LoadData()
        {
            FileManager CacheFile = new FileManager();
            CacheFile.OnReadReady += new Action<StreamReader>(File_OnReadOpen);
            CacheFile.OnReadFileMissing += new Action(File_OnReadFileMissing);
            CacheFile.Read(Common.Constants.ExchangeTmpFile);
        }
        void File_OnReadFileMissing()
        {
            Deployment.Current.Dispatcher.BeginInvoke(
            delegate
            {
                MessageBox.Show("Local file missing, first time application start?", "FileManager OnReadFileMissing exception", MessageBoxButton.OK);
            });
        }

        void File_OnReadOpen(StreamReader Stream)
        {
            using (XmlReader XmlReader = XmlReader.Create(Stream))
            {
                XmlSerializer DataSerializer = new XmlSerializer(typeof(RatesList));
                _RatesList = (RatesList)DataSerializer.Deserialize(XmlReader);
                Rates = _RatesList.Collection;
            }

        }

        #endregion

        #region update data

        public void UpdateData()
        {
            LoadManager DataLoader = new LoadManager();
            DataLoader.OnNoNetwork += new Action(DataLoader_OnNoNetwork);
            DataLoader.OnError += new Action<Exception>(DataLoader_OnError);
            DataLoader.OnStart += new Action(DataLoader_OnStart);
            DataLoader.OnLoad += new Action<string>(DataLoader_OnLoad);
            DataLoader.OnFinish += new Action(DataLoader_OnFinish);
            DataLoader.OnSaveTo += new Action<string>(DataLoader_OnSaveTo);
            DataLoader.SaveTo = Common.Constants.ExchangeTmpFile;
            DataLoader.Load(Common.Constants.ExchangeApiUrl);
        }

        void DataLoader_OnSaveTo(string data)
        {
            FileManager CacheFile = new FileManager();
            CacheFile.WriteBefore = "<Root>";
            CacheFile.WriteAfter = "</Root>";
            CacheFile.Save(Common.Constants.ExchangeTmpFile, data);
        }

        void DataLoader_OnNoNetwork()
        {
            Deployment.Current.Dispatcher.BeginInvoke(
            delegate
            {
                MessageBox.Show("No network available.", "LoadManager OnNoNetwork exception", MessageBoxButton.OK);
            });
        }
        void DataLoader_OnError(Exception e)
        {
            Deployment.Current.Dispatcher.BeginInvoke(
            delegate
            {
                MessageBox.Show(e.Message, "LoadManager OnError exception", MessageBoxButton.OK);
            });
        }
        void DataLoader_OnStart()
        {
            IsProgressVisible = true;
            IsDataLoaded = false;
        }
        void DataLoader_OnFinish()
        {
            IsProgressVisible = false;
        }
        void DataLoader_OnLoad(string data)
        {
            try
            {
                Deployment.Current.Dispatcher.BeginInvoke(
                delegate
                {
                    LoadData();
                    LastUpdate = DateTime.Now;
                });
            }
            catch (Exception ex)
            {
                Deployment.Current.Dispatcher.BeginInvoke(
                delegate
                {
                    MessageBox.Show(ex.Message, "LoadManager OnLoad outer exception", MessageBoxButton.OK);
                });
            }
        }

        #endregion


        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
